你以為JS拿來就乖乖照著我們打的一行一行跑嗎?太天真了,我說我~~
變數怎麼存,存哪裡,在哪裡叫得到變數出來?我們會連續幾天,討論這個問題~
一句話解釋,預編譯是幹蛤的?
根據宣告變數、宣告function的關鍵字,在內存開闢位置給變數、function
執行前一刻,做預編譯:
建立形參
(形式參數)、
建立變數
特別注意:形參
和var
初始化undefined;let
和const
沒有初始化
賦值實參
(實際參數)給形參
建立function
(此時不管function的body是甚麼,執行時才看)
開始執行(function
和變數
這裡才賦值)
function outerFun(){
function innerFun(){};
innterFun();
};
outerFun();
window object
在預編譯的step4:宣告function時,建立了outerFun
window object
執行window object
執行中,執行到outerFun()
時:
outerFun
代碼的前一刻,預編譯outerFun
outerFun
時,建立了innerFun
outerFun
執行outerFun
執行中,執行到innerFun()
時:
innerFun
代碼的前一刻,預編譯innerFun
innerFun
執行整理一下邏輯:
試問:執行時,我愛多早呼叫變數、呼叫function,愛多早就多早,不會報錯,頂多undefined?
是的呀~~因為我已經把宣告變數、宣告function這件事情,提升了嘛~
(這裡也還不是提升的完整版
受限於let有一丟丟的麻煩,這裡只先討論var變數和function
一定會有完整版的放心~~)
var變數的提升:undefined
undefined
→故:var變數的提升,得undefined
function的提升:完整的function(不是空殼function)
小整理:var變數、function甚麼時後有值的(可以往上對照俄羅斯娃娃那裏)
猜猜:是不是用原始值
或引用值
來區分能不能完整提升?
.
.
.
.
.
.
想多了(我就是這樣誤以為)
object,array都是引用值的一種,但他們就不像function object可以整塊完整被提升。
console.dir(o) //undefined
console.dir(b) //undefined
console.dir(f) //f()
var o={
'name':'小o',
'白花':'可曾枯萎呀'
}
var b=['輕聲唱著','少年的模樣','會悲傷會幻想']
function f(){
var name='別去打擾她'
}
//部分歌詞:<<旅行家說>> 毛不易
至於為甚麼只有function可以有這個好康,平平都是引用值,為甚麼object和array沒有呢?
我個人的想像是,因為var變數的作用域(有效範圍)是以function為界,所以才會以function做為單位進行提升。
也不是所有function都會乖乖地提升,那到底是誰怎麼不乖呢?要拜乖乖?
fun1(); //1
fun2(); //Uncaught TypeError: fun2 is not a function
//function聲明
function fun1(){console.log(1)};
//function表達式
var fun2=function(){console.log(2)};
function表達式雖然提升失敗,被說fun2不是一個function不被承認QQ,
但並沒有破壞規則,規則還是原本那個規則喔~~來,上原因
GO{
fun1 : function fun1(){......},
fun2 : undefined
}
沒錯,因為他電腦看到var fun2=
,就覺得他是一個原始值
,不是function引用值
。
殊不知後面等於一個function。失算失算
小結論:能不能像function宣告完整被提升的關鍵因素,是function
關鍵字